#pragma once
#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>

class Request
{
public:
    Request(int x, int y, char op)
    : _x(x)
    , _y(y)
    , _op(op)
    {}
    Request()
    {}

    void Serialize(std::string* out)
    {
        Json::Value root;
        root["x"] = _x;
        root["y"] = _y;
        root["op"] = _op;

        Json::StyledWriter w;
        *out = w.write(root);
    }
    void Deserialize(const std::string& in)
    {
        Json::Value root;
        Json::Reader r;
        r.parse(in, root);

        _x = root["x"].asInt();
        _y = root["y"].asInt();
        _op = root["op"].asInt();
    }

    void PrintVariable()
    {
        std::cout << "数据请求: " << _x << _op << _y << "=?" << std::endl;
    }

public:
    int _x;
    int _y;
    char _op;
};

class Response
{
public:
    Response(int result, int code)
    : _result(result)
    , _code(code)
    {}
    Response()
    {}

    void Serialize(std::string* out)
    {
        Json::Value root;
        root["result"] = _result;
        root["code"] = _code;

        Json::StyledWriter w;
        *out = w.write(root);
    }
    void Deserialize(const std::string& in)
    {
        Json::Value root;
        Json::Reader r;
        r.parse(in, root);

        _result = root["result"].asInt();
        _code = root["code"].asInt();
    }

    void PrintVariable()
    {
        std::cout << "result: " << _result << " code: " << _code << std::endl;
    }

public:
    int _result;
    int _code;
};

const std::string sep = "\n";
std::string Encode(std::string& content)
{
    std::string len = std::to_string(content.size());

    std::string package; //len\ncontent\n
    package += len;
    package += sep;
    package += content;
    package += sep;

    return package;
}
bool Decode(std::string& package_stream, std::string* content) //len\ncontent\nxxxxxxxxxxxxx...
{
    size_t pos = package_stream.find(sep);
    if(pos == std::string::npos)
    {
        return false;
    }
    
    std::string len_str = package_stream.substr(0, pos);
    int len = stoi(len_str);

    int package_len = 2 + len + len_str.size();
    if(package_stream.size() < package_len) //len\ncont
    {
        return false;
    }

    *content = package_stream.substr(pos+1, len);

    package_stream.erase(0, package_len);

    return true;
}